#include"recoProxy.h"
#include"callback.h"
//#include "../data/data.h"
using namespace std;

recoProxy::recoProxy(const char* pUuid, int iUuidLen,void* pCbObj, vadOptions* pVadOptions, asrOptions* pAsrOptions, getResCb pCbFunc)
	:_curFp(NULL)
	//_pCbFunc(pCbFunc)
{
	if (pVadOptions)
	{
		memcpy(&_pVadOptions,pVadOptions,sizeof(vadOptions));
	}
	else
	{
		memset(&_pVadOptions, 0,sizeof(vadOptions));
	}
	processGobalEnv();
	processVadOption(&_pVadOptions);
	if (pAsrOptions)
	{
		memcpy(&_pAsrOptions,pAsrOptions,sizeof(asrOptions));
	}
	else
	{
		memset(&_pAsrOptions,0,sizeof(asrOptions));
	}
	_sReporter = make_shared< reporter> (pUuid, iUuidLen,pCbFunc,pCbObj);
	_pCbUtil = createVadCbUtil(cbProcessVadRes,cbProcessVadClose,cbUpdateTime,this);
	_pVadInst = recoProxyCreateVad(&_pVadOptions,_pVadOptions._iVadRenderId,_pCbUtil);
	_pAsrInst = make_shared< iflytekAsrInst>(_sReporter);
	_pAsrInst->init();
	//_pVadInst->init();
	recoProxyInitVad(_pVadInst);
#ifdef LOGFILE
	//log::getInstance()->init();
#endif
}
void recoProxy::feedData(char* pData, int iLen)
{
	recoProxyVadFeedData(_pVadInst,pData,iLen);
}
void recoProxy::openDbgFile(int iIndex)
{
	vadOptions* pOptions = getOptions();
	char* filePath = pOptions->_vadFilePath;
	int iFilePathLen = pOptions->_iVadFilePathLen;
	char* fileName = new char[iFilePathLen + 1 + strlen(getReporter()->getUuid()) + 10 ];
	sprintf(fileName,"%s/%s_%04d.pcm",filePath,getReporter()->getUuid(),iIndex);
	getReporter()->setFileName(fileName,strlen(fileName));
	_curFp = fopen(fileName,"wb");
	//need handle special case
	delete [] fileName;
}
void recoProxy::closeDbgFile()
{
	if(_curFp)
		fclose(_curFp);
	_curFp = NULL;
}
void recoProxy::outputDbgFile(void* pContent, int iLen)
{
	if(iLen > 0)
		fwrite(pContent,iLen,sizeof(char),_curFp);
}
void recoProxy::processVadRes( unsigned char * pData, int iLen, vadVars* pVars)
{
	//first frame
	if (pVars->_iIsBegin)
	{
		if(iLen > 0)
		{
			fprintf(stdout, "---Get data len %d\n",iLen);
			if(iLen > 640)
			{
				int iCurLen = 0;
				int iDelta = 640;
				if(pVars->_iFirstFrame)
				{
					_pAsrInst->sendFirstMsg(FRAME_FIRST,pData,iDelta,pVars->_iIndex);
					openDbgFile(pVars->_iIndex);
					outputDbgFile(pData,iDelta);
					pVars->_iFirstFrame = 0;
				}
				else
				{
					_pAsrInst->sendMsg(FRAME_CONT,pData,iDelta);
					outputDbgFile(pData,iDelta);
				}
				//fprintf(stdout,"FRAME FRIST\n");
				iCurLen = iDelta;
				while (iCurLen < iLen- iDelta)
				{
					_pAsrInst->sendMsg(FRAME_CONT,pData+iCurLen,iDelta);			
					outputDbgFile(pData+iCurLen,iDelta);
					iCurLen += iDelta;
				}
				_pAsrInst->sendMsg(FRAME_CONT,pData+iCurLen,iLen -iCurLen);
				outputDbgFile(pData+iCurLen,iLen -iCurLen);
			}
			else
			{
				if(pVars->_iFirstFrame)
				{
					_pAsrInst->sendFirstMsg(FRAME_FIRST,pData,iLen,pVars->_iIndex);
					openDbgFile(pVars->_iIndex);
					pVars->_iFirstFrame = 0;
				}
				else
				{
					_pAsrInst->sendMsg(FRAME_CONT,pData,iLen);
					outputDbgFile(pData,iLen);
				}
			}
		}
	}
	//last frame
	else if (1 == pVars->_iIsEnd)
	{
		//if(vadlen > 0)
		_pAsrInst->sendMsg(FRAME_LAST,pData,iLen);
		outputDbgFile(pData,iLen);
		closeDbgFile();
	}
	else
	{
		if(iLen > 0)
		{
			_pAsrInst->sendMsg(FRAME_CONT,pData,iLen);
			outputDbgFile(pData,iLen);
		}
	}
}
void recoProxy::updateTime(int iType, int iTime)
{
	if( VAD_TIME_START == iType)
	{
		getReporter()->setBeginTime(iTime);
	}
	else if(VAD_TIME_END == iType)
	{
		getReporter()->updateEndTime(iTime);
	}
	else assert(0);
}
void recoProxy::close()
{
	recoProxyCloseVad(_pVadInst);
	//_pVadInst->close();
	_sReporter->bye();
}
